from flask import abort, jsonify
from flask import current_app
from flask import g
from flask import render_template
from flask import request
from flask import session

from info import db
from info.Modules.news import news_blu
from info.models import User, News, Comment, CommentLike
from info.utils.common_grep import user_login_data
from info.utils.response_code import RET


#点赞后端接口
@news_blu.route("/comment_like",methods = ['post'])
@user_login_data
def comment_like():
    """
    +    一、前端
    +    1、当我点赞的时候，手变蓝色，赞变成1
    +    2、如果用户没有登录，需要弹出登录框
    +    3、当我们取消点赞，变为原有状态
    +
    +    二、后端
    +    1、需要user 和 comment_id  action
    +    2、ajax. post
    +    :return:
    +    """
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="不再")
    # 1、接收参数
    params_dict = request.json
    comment_id = params_dict.get('comment_id')
    action = params_dict.get('action')
    # 2、校验参数
    if not all([comment_id,action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    if action not in ['add','remove']:
        return jsonify(errno=RET.PARAMERR, errmsg="action参数错误")
    try:
        comment_id = int(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    try:
        comment_list = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    if not comment_list:
        return jsonify(errno=RET.NODATA, errmsg="新闻评论不存在")


    #5、查询所有点赞对象中是否有 评论id ,user_id 与本条评论和用户id 一致得对象
    comment_like_obj =CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                               CommentLike.user_id == user.id).first()

    #判断action得值  如果等于add  创建点赞对象  否则 删除对象
    if action == 'add':
        if not comment_like_obj:   #没有点赞，就添加  有就不操作
            comment_like = CommentLike()
            comment_like.comment_id = comment_id
            comment_like.user_id = user.id
            db.session.add(comment_like)
            comment_list.like_count +=1
    else:
        if comment_like_obj:
            db.session.delete(comment_like_obj)
            comment_list.like_count -= 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.NODATA, errmsg="数据库操作失败")
    return jsonify(errno=RET.OK, errmsg="成功")









#评论后端接口
@news_blu.route("/news_comment",methods = ['post'])
@user_login_data
def news_comment():
    """
    +    新闻评论
    +    1、接收参数
    +    2、校验参数
    +    3、业务逻辑  初始化一个评论对象 添加到数据库
    +    4、返回响应
    +    :return:
    +    """
    user =g.user
    if not user:
        return jsonify(errno=RET.PARAMERR, errmsg="没人")
    # 1、接收参数
    params_dict = request.json
    news_id= params_dict.get('news_id')
    comment_content = params_dict.get('comment')
    parent_id = params_dict.get('parent_id')
    #2、校验参数
    if not all([news_id,comment_content]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    try:
        news_id = int(news_id)
        if parent_id:
            parent_id = int(parent_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    try:
        news =News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")
     #3、业务逻辑
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news_id
    comment.content = comment_content
    if parent_id:
        comment.parent_id = parent_id
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据库保存失败")
    return jsonify(errno=RET.OK, errmsg="成功" ,data=comment.to_dict())




#收藏后端接口
@news_blu.route('/news_collect',methods=["post"])
@user_login_data
def news_collect():
    """
    +    新闻收藏
    +    1、接收参数
    +    2、校验参数
    +    3、查询出该条新闻
    +    4、往用户收藏新闻的列表中添加新闻
    +    5、返回响应
    +    :return:
    +    """
    #判断用户登录状态
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登陆")

    # 1、接收参数
    params_dict =request.json
    news_id = params_dict.get('news_id')
    action = params_dict.get('action')
    #2、校验参数
    print(news_id)
    print(action)
    if not all([news_id,action]):
        return jsonify(errno=RET.NODATA, errmsg="参数不全")
    try:
        news_id = int(news_id)
    except Exception as e:
        return jsonify(errno=RET.PARAMERR, errmsg="参数news_id错误")
    if action not in ['collect', 'cancel_collect']:
        return jsonify(errno=RET.NODATA, errmsg="参数action错误")
    #3、查询出该条新闻
    try:
        news_list = News.query.get(news_id)  #[obj,obj]
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    #判断取出的news_list是否存在，可能为null
    if not news_list:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")

    #4、往用户收藏新闻的列表中添加新闻或在删除(取消)收藏
    print(news_list)
    if action == 'collect':
        # return jsonify(errno=RET.PARAMERR, errmsg="该新闻已经被收藏")
        if news_list not in user.collection_news:
            user.collection_news.append(news_list)
    else:
        if news_list in user.collection_news:
            user.collection_news.remove(news_list)
    #5、返回响应
    return jsonify(errno=RET.OK, errmsg="成功")





@news_blu.route("/<int:news_id>")
@user_login_data
def detail(news_id):
    #为了进入详情页右上角后期前端可以显示用户信息
    # user_id =session.get('user_id')   #用户id
    # if user_id:
    #     try:
    #         user = User.query.get(user_id)   #去数据库查出该用户信息
    #     except Exception as e:
    #         current_app.logger.error(e)
    #显示详情页里右边点击排行的新闻
    user =g.user
    news_list = News.query.order_by(News.clicks.desc()).limit(6).all()  #[obj,obj]

    news_dict_li =[]
    for news_obj in news_list:
        news_dict_li.append(news_obj.to_dict())


    #二查询所有新闻信息
    news = None
    try:
        news =News.query.get(news_id)  #news 是新闻对象 [obj]
    except Exception as e:
        current_app.logger.error(e)
        abort(500)
    #判断取出的是否存在
    if not news:   # 上面定义的news=None 如果数据库查询失败，这里也不会报错
        abort(404)

    news.clicks += 1

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        abort(500)

    #收藏按钮显示  如果该新闻在用户收藏夹中
    is_collected = False
    if user:
        if news in user.collection_news:
            is_collected = True

    #三查询评论
    # 1、获取到本条新闻下所有的评论对象列表
    comment_list = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()    #对象

    #页面刷新点赞还在

    #2、将获取到的评论对象列表中所有对象的id存到一个评论id列表中
    comment_id_list =[]
    for comments in comment_list:
        comment_id_list.append(comments.id)
    #3、获取点赞对象中所有（user_id= user.id并且comment_id 在 评论id列表中）的所有点赞对象列表；
    # 将这个列表中所有对象的comment_id取出来存到一个comment_like_ids列表中
    comment_like_objs= CommentLike.query.filter(CommentLike.user_id == user.id,
                            CommentLike.comment_id.in_(comment_id_list)).all()
    #把我点赞的所有评论id 装到一个列表下面要用
    comment_like_obj_ids =[]
    for comment_like_obj in comment_like_objs:
        comment_like_obj_ids.append(comment_like_obj.comment_id)
    #4、遍历第一条中的列表 将对象转化成字典  添加一个'is_like':Flase 键值对 ；
    comment_dict = []
    for comments in comment_list:
        comments_dict = comments.to_dict()
        comments_dict['is_like'] =False

        if comments.id in comment_like_obj_ids:
            comments_dict['is_like'] = True
        comment_dict.append(comments_dict)


    # 判断 如果对象的id在comment_like_ids 中 就将 'is_like'的值 改成True


    #传给前端 用户信息user 和 右边点击排行的新闻
    data ={'news_dict':news_dict_li,
           'user_info':user.to_dict() if user else None,
           'news':news.to_dict(),
           'is_collected':is_collected,
           "comments":comment_dict
           }

    return render_template('news/detail.html',data =data)
